/*!
  @file message.h
  @copyright 2013 Kubota Lab. All rights resereved.
*/

#ifndef _NET_MESSAGE_H_
#define _NET_MESSAGE_H_

#include <boost/scoped_ptr.hpp>

namespace net {

/*! 
 *  @brief  Message base class
 *  @author Kyohei Otsu <kyon@ac.jaxa.jp>
 *  @date   2013
 *  
 *  inherit this class by specific messages
 *    e.g.) class StringMsg : public Message;
 *  override virtual functions
 *
 *  header = id(4) + body_length(4)
 */

class Message {
 public:
  enum { HEADER_LEN = 8, };

  Message() 
      : id_(0)
      , data_len_(0)
  {}

  ~Message() { }

  //! return the pointer to the data (i.e., head of header)
  char* data() { return data_.get(); }

  //! encodes the data to char*
  const char* encode();

  //! decodes char* to header and body
  void decode();

  //! return the length of whole data (header + body)
  virtual size_t length() const { return HEADER_LEN + getBodyLength(); }

 protected:
  //! parses char* to the data. 
  /*! The inherited class must be override this function */
  virtual void setBodyData(char* body, size_t body_len) = 0;
  
  //! returns the char pointer to the head of the data
  /*! The inherited class must be override this function */
  virtual const char* getBodyData() const = 0;

  //! returns the length of body in char[]
  /*! The inherited class must be override this function */
  virtual const size_t getBodyLength() const = 0;

  //! allocs memory if necessary
  void resize();

  //! data specific id 
  /*! this must be set by the inherited class */
  size_t id_;

  boost::scoped_ptr<char> data_;
  size_t data_len_; 
};

#include "net/message/impl/message-impl.h"

}  // namespace net

#endif
